#include "CSettings.h"

namespace onet
{
    CSettings::CSettings(bool autoSave_) : autoSave(autoSave_), loaded(false)
    {
    }

    CSettings::~CSettings()
    {
        if (autoSave)
            this->save();
    }

    //! Set the file manually
    //! Use absolute path!
    void CSettings::setFile(std::string str)
    {
        fileName = str;
    }

    //! Automatically creates/reads a file in the private folder of the user
    void CSettings::autoSetFile(std::string str, bool hidden)
    {
        std::string path = getenv("HOME");

        if(!path.size())
            std::cout << "Warning: Can't get home folder" << std::endl;

        path += "/";

        if(hidden)
            path += ".";

        path += str;

        std::cout << "Settings path: " << path << std::endl;

        this->setFile(path);
    }

    //! Saves the config
    bool CSettings::save()
    {
        std::ofstream file;

        file.exceptions ( std::ofstream::eofbit | std::ofstream::failbit | std::ofstream::badbit );

        try
        {
            file.open(fileName.c_str(), std::ios_base::trunc);

            for(std::map<std::string, std::string>::iterator it = values.begin(); it != values.end(); it++)
            {
                file << (*it).first << "=" << (*it).second << std::endl;
            }

            file.close();

            return true;
        }
        catch(std::ofstream::failure e)
        {
            std::cout << "I/O Error:" << e.what() << std::endl;

            return false;
        }
    }

    //! Load config from file
    bool CSettings::load()
    {
        std::ifstream file;
        std::string name;
        std::string parameter;
        bool isName;
        c8 c;

        isName = true;

        file.open(fileName.c_str());

        if (file.fail())
            return false;

        while (file.get(c))
        {
            if (c == '=')
            {
                isName = false;

            }
            else if (c == '\n')
            {
                values[name] = parameter;

                parameter = "";
                name = "";
                isName = true;
            }
            else
            {
                if (isName)
                    name += c;
                else
                    parameter += c;
            }
        }

        file.close();

        loaded = true;

        return true; //! Everything went well
    }

    //! Gets the path/name of config-file
    std::string CSettings::getFileName()
    {
        return fileName;
    }

    //! Sets values
    void CSettings::setString(std::string name, std::string val)
    {
        values[name] = val;
    }

    void CSettings::setInteger(std::string name, s32 val)
    {
        std::stringstream sstr;

        sstr << val;

        values[name] = sstr.str();
    }

    void CSettings::setBool(std::string name, bool val)
    {
        if(val)
            values[name] = "true";
        else
            values[name] = "false";
    }

    //! Gets values
    s32 CSettings::getInteger(std::string name, s32 def)
    {
        std::map<std::string, std::string>::iterator it = values.find(name);

        if (it == values.end())
            return def;

        return atoi((*it).second.c_str());
    }

    bool CSettings::getBool(std::string name, bool def)
    {
        std::map<std::string, std::string>::iterator it = values.find(name);

        if (it ==  values.end())
            return def;

        std::string parameter = (*it).second;

        if (parameter == "true" || parameter == "yes" || parameter=="1")
            return true;
        else
            return false;
    }

    std::string CSettings::getString(std::string name, std::string def)
    {
        std::map<std::string, std::string>::iterator it =  values.find(name);

        if (it ==  values.end())
            return def;
        else
            return (*it).second;
    }

    //! Is saving on quitting?
    bool CSettings::isAutoSaving()
    {
        return autoSave;
    }

    void CSettings::setAutoSaving(bool newval)
    {
        autoSave = newval;
    }

    bool CSettings::isLoaded()
    {
        return loaded;
    }

}
